<template>
  <div ref="gridRef" :class="['grid', border && 'grid-border', className]" :style="gridStyle">
    <slot />
    <template v-for="(item, index) in template" :key="item?.key || index">
      <Item
        v-if="item?.element"
        :col-span="item.colSpan"
        :row-span="item.rowSpan"
        :style="item.style"
        :transfer-style="transferStyle"
        @click="handleItemClick(index)"
      >
        <component :is="item.element" />
      </Item>
    </template>
  </div>
</template>

<script setup>
import { ref, computed, provide } from 'vue';
import Item from './item.vue';

const props = defineProps({
  border: Boolean,
  template: {
    type: Array,
    default: () => [],
  },
  column: Number,
  gap: [String, Number],
  option: {
    type: Object,
    default: () => ({}),
  },
  transferStyle: Boolean,
  onItemClick: Function,
  className: String,
  style: Object,
});

provide('GridContext', {
  defaultTransferStyle: props.transferStyle,
});

const emit = defineEmits(['item-click']);
const gridRef = ref(null);

const gridStyle = computed(() => ({
  gap: props.gap || props.option.gap,
  gridTemplateColumns: `repeat(${props.column || 1}, 1fr)`,
  ...props.style,
}));

const handleItemClick = (index) => {
  props.onItemClick?.(index);
  emit('item-click', index);
};

defineExpose({ ref: gridRef });
</script>

<style>
.grid {
  display: grid;
  box-sizing: border-box;
}

.grid-border {
  gap: 1px;
  outline: 1px solid var(--color-border, #d9d9d9);

  & > .grid-item {
    outline: 1px solid var(--color-border, #d9d9d9);
    margin-bottom: 0;
    padding: var(--size-cell-gap, 16px);
  }
}
</style>
